package com.atguigu.gmall.order.api;


import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.result.ResultCodeEnum;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderDetailVo;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.order.service.OrderDetailService;
import com.atguigu.gmall.order.service.OrderService;
import com.atguigu.gmall.order.to.OrderSplitTo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.swagger.models.auth.In;
import org.omg.PortableInterceptor.ObjectReferenceFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;



@RequestMapping("/api/order")
@RestController
public class OrderController {


    @Autowired
    OrderService orderService;

    @Autowired
    OrderDetailService orderDetailService;


    /**
     * 库存系统在进行库存扣减需要的时候会给我们发送拆单逻辑
     * @return 返回子订单集合
     */
    @PostMapping("orderSplit")
    public List<OrderSplitTo> orderSplit(@RequestParam("orderId") Long orderId,
                                         @RequestParam("wareSkuMap") String wareSkuMap) throws JsonProcessingException {

        return orderService.splitOrder(orderId,wareSkuMap);



    }


    @GetMapping("/orderinfo/details/outTradeNo")
    public OrderInfo getOrderInfoWithDetailsByOutTradeNo(@PathVariable("outTradeNo") String outTradeNo){

        return orderService.getOrderInfoWithDetailsByOutTradeNo(outTradeNo);
    }


    @GetMapping("/auth/{pageNo}/{pageSize}")
    public Result getOrdersByPage(@PathVariable("pageNo") Integer pageNo,
                                  @PathVariable("pageSize") Integer pageSize,
                                  HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        //查询当前用户的
        Page<OrderInfo> page = new Page<>(pageNo,pageSize);
        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("user_id",userId);
         queryWrapper.orderByDesc("id");

        Page<OrderInfo> infoPage = orderService.page(page, queryWrapper);
        List<OrderInfo> recodes = infoPage.getRecords();
        for (OrderInfo recode : recodes) {
            QueryWrapper<OrderDetail> wrapper = new QueryWrapper<>();
            wrapper.eq("order_id",recode.getId());
            List<OrderDetail> list = orderDetailService.list();
            recode.setOrderDetailList(list);
        }
        return Result.ok(infoPage);
    }

    @GetMapping("/payed/success")
    public String changeOrderStatuPayed(@RequestParam("outTradeNo") String outTradeNo){
        orderService.changeOrderStatusPayed(outTradeNo, OrderStatus.PAID.name());
        return "ok";

    }


    @GetMapping("/getorder/{id}")
    public OrderInfo getOrderById(@PathVariable("id") Long orderId){
        OrderInfo byId = orderService.getById(orderId);
        return byId;
    }


    /**
     * //api/order/auth/submitOrder?tradeNo=dsajlkdjalkjd
     * 前端提交的AJAX将所有订单数据全部带过来。
     * @param tradeNo  防重令牌
     * @param orderInfo 前端提交的订单相关数据
     * @return
     */
    @PostMapping("/auth/submitOrder")
    public Result submitOrder(@RequestParam(value = "tradeNo",required = true) String tradeNo,
                              @RequestBody OrderInfo orderInfo,
                              HttpServletRequest request){
        String userId = AuthContextHolder.getUserId(request);
        //1、先验证令牌 tradeNo
        if(!orderService.checkToken(userId,tradeNo)){
            //验证失败
            return Result.build(null, ResultCodeEnum.REPEAT_SUBMIT);
        };

        //哪些商品的价格发生变动，让前端重新确认（页面刷新一下，显示新价格，如果用户接受就继续提交）
        //哪些商品没有库存，要提示用户从购物车中自己移除没有库存的商品
        // 基本上电商都是允许超卖【秒杀】。 （想的不是解决超卖，而是解决供应链）
        // 超出数量以后（供应链速度快的）  一件代发，第二天发货就行
        // 正常订单允许超卖
        List<String> errMsg = orderService.checkSkuPriceAndStock(orderInfo.getOrderDetailList());
        if(!CollectionUtils.isEmpty(errMsg)){
            //前面的验证失败
            Result<Object> fail = Result.fail();
            String join = String.join(",", errMsg);
            fail.setMessage(join);
            return fail;
        }
        //验价;  把前端提交来得订单价格和当前商品真的价格进行比对。
        //一样，正常下单。不一样，返回失败，并提示哪个商品价格有变化
        //验库存（基于我们不允许超卖）；确保当前订单的商品库存是有的，
        //feign接口已经有了。挨个验证是否有货
        //锁库存 【下单锁(X)，支付成功锁(V)】

        //【下单的这一刻】锁住库存。库存数量同时减一下。 12306买票；我们是支付锁
        // TODO 订单长时间不支付，订单会被自动取消。 【释放库存】
        //生成订单：给数据库创建订单。保存两张表。
        //order_info    order_details
        // 前置校验通过，生成订单。
        orderInfo.setUserId(Long.parseLong(userId)); //往下传递用户id
        OrderInfo createOrder = orderService.createOrder(orderInfo);
        // 订单id怎么生成。直接有工具类，普通的id生成办法
        Long id = createOrder.getId(); //假装为雪花后的id

        //库存系统不用编写，锁定库存（支付成功锁）


        // 成功，前端用js直接跳到 http://payment.gmall.com/pay.html?orderId=
        return Result.ok(id);  //自动跳到支付页
    }
}
